// GrandiaX Mana Egg Table GeneratorView.cpp : implementation of the CGrandiaXBattleItemView class
//

#include "stdafx.h"
#include "GrandiaX Mana Egg Table Generator.h"

#include "GrandiaX Mana Egg Table Generator Doc.h"
#include "GrandiaX Battle Item View.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static const int Gap = 2;

static const int MagicHeight = 30;


static const int Widths[] = {300, 60, 80, 100}; // , GAP=80, Party

static int x2Right(int x);

static int x2Left(int x)
{
    if (x<=0)
    {
        return Gap;
    }

    return Gap + x2Right(x-1); 
}

static int x2Right(int x)
{
    return x2Left(x) + Widths[x];
}


enum
{
    UID_ITEM = 1000,
    UID_COUNT = 2000,   
    UID_PARTY = 3000,
};


/////////////////////////////////////////////////////////////////////////////
// CGrandiaXBattleItemView

IMPLEMENT_DYNCREATE(CGrandiaXBattleItemView, CScrollView)

BEGIN_MESSAGE_MAP(CGrandiaXBattleItemView, CScrollView)
    //{{AFX_MSG_MAP(CGrandiaXBattleItemView)
    ON_WM_CTLCOLOR()
    //}}AFX_MSG_MAP
ON_WM_DESTROY()
ON_WM_TIMER()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGrandiaXBattleItemView construction/destruction

CGrandiaXBattleItemView::CGrandiaXBattleItemView()
{
}

CGrandiaXBattleItemView::~CGrandiaXBattleItemView()
{

}

BOOL CGrandiaXBattleItemView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs

    return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CGrandiaXBattleItemView drawing

void CGrandiaXBattleItemView::OnDraw(CDC* pDC)
{
}

/////////////////////////////////////////////////////////////////////////////
// CGrandiaXBattleItemView printing

BOOL CGrandiaXBattleItemView::OnPreparePrinting(CPrintInfo* pInfo)
{
    // default preparation
    return DoPreparePrinting(pInfo);
}

void CGrandiaXBattleItemView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add extra initialization before printing
}

void CGrandiaXBattleItemView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CGrandiaXBattleItemView diagnostics

#ifdef _DEBUG
void CGrandiaXBattleItemView::AssertValid() const
{
    CScrollView::AssertValid();
}

void CGrandiaXBattleItemView::Dump(CDumpContext& dc) const
{
    CScrollView::Dump(dc);
}

CGrandiaXManaEggTableGeneratorDoc* CGrandiaXBattleItemView::GetDocument() // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGrandiaXManaEggTableGeneratorDoc)));
    return (CGrandiaXManaEggTableGeneratorDoc*)m_pDocument;
}
#endif //_DEBUG


void CGrandiaXBattleItemView::OnInitialUpdate() 
{
    CScrollView::OnInitialUpdate();

    int x = 1;
    int y = 0;

#define ITEM_RECT CRect(Gap + x2Left(x), y*(MagicHeight + Gap) + Gap,\
x2Right(x), (y+1)*(MagicHeight+Gap) )

#define ITEM_RECT_STATUS CRect(Gap + x2Left(x), y*(MagicHeight + Gap) + Gap,\
x2Right(x), (y+2)*(MagicHeight+Gap) )

#define DROPDOWN_ITEM_RECT CRect(Gap + x2Left(x), y*(MagicHeight + Gap) + Gap,\
x2Right(x), (y+20)*(MagicHeight+Gap) )

    if (!Item[0].m_hWnd)
    {
        for (int s=0;s<30;s++) // slot
        {
            x = 0;
            
            Item[s].Create(CBS_DROPDOWNLIST|WS_CHILD|WS_VISIBLE|WS_VSCROLL,
                DROPDOWN_ITEM_RECT, this, UID_ITEM+s);
             
            int ItemMapCounter = 0;
        
            for (int i=0;i<2001;i++)
            {
                char name[240];

                if (GetDocument()->GetItemName(i, name))
                {
                    ItemMap[i] = ItemMapCounter;

                    if (name[0])
                    {
                        Item[s].AddString(name);
                        ItemMapCounter++;
                    }

                }
                else
                {
                    break;
                }
            }

           x++;

            Count[s].Create(WS_CHILD|WS_VISIBLE|ES_NUMBER|WS_BORDER,
                ITEM_RECT, this, UID_COUNT+s);            

            y++;
        }

        x = 3;

        y = 0;

        for (int p=0; p<4; p++)
        {
            Party[p].Create(CBS_DROPDOWNLIST|WS_CHILD|WS_VISIBLE|WS_VSCROLL,
                DROPDOWN_ITEM_RECT, this, UID_PARTY+p);

            Party[p].AddString("N/A"); 

            for (int i=0;i<8;i++)
            {
                const char* name = GetDocument()->GetCharacterName(i);

                 Party[p].AddString(name);               
            }

            y++;
        }

        y = 30;
        
        SetScrollSizes(MM_TEXT, CSize(x2Right(x), y*(MagicHeight+Gap) + Gap) );
    }

    StartInspecting();
}

void CGrandiaXBattleItemView::UpdateBattleItems()
{
    char Text[256];

    for (int s=0; s<30; s++)
    {
        Item[s].SetCurSel(ItemMap[BattleItems[s].Item]);
        
        _itot(BattleItems[s].Count, Text, 10);
        Count[s].SetWindowTextA(Text);
    }

}

BOOL CGrandiaXBattleItemView::OnCommand(WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class

    int slot = -1;
    int party = -1;

    if (HIWORD(wParam) == CBN_SELCHANGE)
    {
        int lw = LOWORD(wParam);

        if (lw >= UID_PARTY)
        {
            party = lw - UID_PARTY;
        }
        else if (lw >= UID_ITEM)
        {
            slot = lw - UID_ITEM;
        }
    }
    else if(HIWORD (wParam) == EN_CHANGE)
    {
        int lw = LOWORD(wParam);    

        if (lw >= UID_COUNT)
        {
            slot = lw - UID_COUNT;
        }

    }

    if (slot>=0)
    {
        CHAR Text[256];

        Item[slot].GetWindowText(Text, 256);

        Text[4] = 0;

        int item = _ttoi(Text);

        int count = EditToInt(Count[slot]);

        if ((count == 0) && (item != 0))
        {
            count = 1;

            Count[slot].SetWindowText(TEXT("1"));
        }

        SetBattleItem(slot, item, count);
    }
    else if (party>=0)
    {
        PartyData[party] = Party[party].GetCurSel();

        GrandiaXLiveModifierWrite(PartyData);
    }

    return CScrollView::OnCommand(wParam, lParam);
}

void CGrandiaXBattleItemView::StartInspecting()
{
    InspectTimer = SetTimer(1, 250, NULL);
}

void CGrandiaXBattleItemView::StopInspecting()
{
    KillTimer(InspectTimer);
}

void CGrandiaXBattleItemView::SetBattleItem(int Slot, int Item, int Count)
{
    BattleItems[Slot].Item = Item;
    BattleItems[Slot].Count = Count;

    GrandiaXLiveModifierWrite(BattleItems);
}

void CGrandiaXBattleItemView::OnDestroy()
{
    StopInspecting();

    CScrollView::OnDestroy();
}

void CGrandiaXBattleItemView::CheckBattleItems()
{
    BATTLE_ITEM_DATA PreReadGameData[30];

    while (1)
    {
        BATTLE_ITEM_DATA GameData[30];

        if (!GrandiaXLiveModifierRead(GameData))
        {
            return;
        }

        if (memcmp(&PreReadGameData, &GameData, sizeof(GameData))==0)
        {
            break;
        }

        memcpy(&PreReadGameData, &GameData, sizeof(GameData));

        Sleep(200);
    }

    if (memcmp(&PreReadGameData, &BattleItems, sizeof(BattleItems))==0)
    {
        return;
    }

    memcpy(&BattleItems, &PreReadGameData, sizeof(BattleItems));

    UpdateBattleItems();
}


void CGrandiaXBattleItemView::CheckPartyData()
{
    PARTY_DATA PreReadGameData[4];

    while (1)
    {
        PARTY_DATA GameData[4];

        if (!GrandiaXLiveModifierRead(GameData))
        {
            return;
        }

        if (memcmp(&PreReadGameData, &GameData, sizeof(GameData))==0)
        {
            break;
        }

        memcpy(&PreReadGameData, &GameData, sizeof(GameData));

        Sleep(200);
    }

    if (memcmp(&PreReadGameData, &PartyData, sizeof(PartyData))==0)
    {
        return;
    }

    memcpy(&PartyData, &PreReadGameData, sizeof(PartyData));

    for (int p=0; p<4; p++)
    {
        Party[p].SetCurSel(PartyData[p]);
    }
}



void CGrandiaXBattleItemView::OnTimer(UINT_PTR nIDEvent)
{
    if (!GrandiaXLiveModifierIsActive())
    {
        return;
    }

   CheckBattleItems();

   CheckPartyData();

    CScrollView::OnTimer(nIDEvent);
}
